/**
 * Projekt do předmetu GJA - LATEX TABLE CREATOR
 *
 * Soubor: MultiSpanCellTableUI.java
 *
 * @author Ondřej Kubal  <xkluba00@stud.fit.vutbr.cz>
 * @author Petr Šimon    <xsimon10@stud.fit.vutbr.cz>
 */

package table;

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;

/**
 *  Jedná se o přepsaný BasicTableUI pro potřeby zobrazování sloučených buňek.
 */
public class MultiSpanCellTableUI extends BasicTableUI
{
     /**
      * Vykreslí celou tabulku
      * @param g     Odkaz na <code>Graphics</code>. Vykreslování.
      * @param c     Konponenta (nevyužito).
      */
     @Override public void paint(Graphics g, JComponent c)
     {
          Rectangle oldClipBounds = g.getClipBounds();
          Rectangle clipBounds    = new Rectangle(oldClipBounds);
          
          //získáme šířku tabulky
          int tableWidth   = table.getColumnModel().getTotalColumnWidth();
          
          //oblast k vykreslení         //oblast        //tabulka
          clipBounds.width = Math.min(clipBounds.width, tableWidth);
          g.setClip(clipBounds);
          
          int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y));
          int  lastIndex = table.getRowCount() - 1;
          
          
          int y = 0;
          
          for (int i = 0; i < firstIndex; i++) //vypočítáme polohu řádku 1. řádku
               //výška řádku           //okraj
               y += table.getRowHeight(i) + table.getRowMargin();
               
          for (int index = firstIndex; index <= lastIndex; index++)
          {
               //oblast jednoho řádku k vykreslení
               Rectangle rowRect = new Rectangle(0, y, tableWidth, table.getRowHeight(index) + table.getRowMargin());
               
               if (rowRect.intersects(clipBounds))
               {
                    //System.out.println();                  // debug
                    //System.out.print("" + index +": ");    // row
                    paintRow(g, index); //vykreslíme řádek
               }
               
               rowRect.y +=  rowRect.height; //navýšíme aktuální y pozici o aktuální výšku řádku
          }
          
          g.setClip(oldClipBounds);
     }
     
     /**
      * Vykreslí jeden konkrétní řádek.
      * @param g     Odkaz na <code>Graphics</code>. Vykreslování.
      * @param row   číslo řádku
      */
     private void paintRow(Graphics g, int row)
     {
          Rectangle rect = g.getClipBounds();
          boolean drawn  = false;
          
          //model
          AttributiveCellTableModel tableModel = (AttributiveCellTableModel)table.getModel();
          //atributy
          CellSpan cellAtt = (CellSpan)tableModel.getCellAttribute();
          //počet sloupců
          int numColumns = table.getColumnCount();
          
          for (int column = 0; column < numColumns; column++)
          {
               Rectangle cellRect = table.getCellRect(row, column, true);
               int cellRow, cellColumn;
               
               if (cellAtt.isVisible(row, column)) //detekce skryté buňky
               {
                    cellRow    = row;
                    cellColumn = column;
                    //  System.out.print("   "+column+" ");  // debug
               }
               else
               {
                    cellRow    = row + cellAtt.getSpan(row, column)[CellSpan.ROW];
                    cellColumn = column + cellAtt.getSpan(row, column)[CellSpan.COLUMN];
                    //  System.out.print("  ("+column+")");  // debug
               }
               
               if (cellRect.intersects(rect))
               {
                    drawn = true;
                    paintCell(g, cellRect, cellRow, cellColumn); //vykreslíme jednu konkrétní buňku
               }
               else
               {
                    if (drawn) break;
               }
          }
          
     }
     
     /**
      * Vykreslí jednu konkrétní buňku.
      * @param g     Odkaz na <code>Graphics</code>. Vykreslování.
      * @param row   číslo řádku
      * @param column číslo sloupce
      */
     private void paintCell(Graphics g, Rectangle cellRect, int row, int column)
     {
          int spacingHeight = table.getRowMargin();
          int spacingWidth  = table.getColumnModel().getColumnMargin();
          
          Color c = g.getColor();
          g.setColor(table.getGridColor());
          g.drawRect(cellRect.x, cellRect.y, cellRect.width - 1, cellRect.height - 1);
          g.setColor(c);
          
          cellRect.setBounds(cellRect.x + spacingWidth / 2, cellRect.y + spacingHeight / 2,
                             cellRect.width - spacingWidth, cellRect.height - spacingHeight);
                             
          if (table.isEditing() && table.getEditingRow() == row &&
                    table.getEditingColumn() == column)
          {
               Component component = table.getEditorComponent();
               component.setBounds(cellRect);
               component.validate();
          }
          else
          {
               TableCellRenderer renderer = table.getCellRenderer(row, column);
               Component component = table.prepareRenderer(renderer, row, column);
               
               if (component.getParent() == null)
               {
                    rendererPane.add(component);
               }
               
               //zavoláme renderer
               rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y,
                                           cellRect.width, cellRect.height, true);
          }
     }
}

